package com.lsq.tucao.user.service.Impl;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lsq.tucao.user.pojo.RoleDetail;
import com.lsq.tucao.user.pojo.UserDetail;
import com.lsq.tucao.user.pojo.po.*;
import com.lsq.tucao.user.dao.*;
import com.lsq.tucao.user.response.JsonResult;
import com.lsq.tucao.user.service.UserService;
import com.lsq.tucao.user.utils.JWTUtils;
import com.lsq.tucao.user.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Slf4j
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    /**
     * normal角色Id
     */
    private final Long ROLE_NORMAL_ID = 1L;
    /**
     * admin角色Id
     */
    private final Long ROLE_ADMIN_ID = 2L;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public JsonResult getUserDetailByName(String username) {
        UserDetail userDetail = new UserDetail();

        User user = userMapper.selectUserByName(username);
        if (user != null) {
            userDetail.setUser(user);

            //获取该用户具有的角色
            QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
            userRoleQueryWrapper.eq("user_id", user.getUserId());
            List<UserRole> userRoles = userRoleMapper.selectList(userRoleQueryWrapper);

            if (userRoles != null) {

                List<RoleDetail> roleDetailList = new ArrayList<>();

                for (UserRole userRole : userRoles) {
                    Long roleId = userRole.getRoleId();
                    Role role = roleMapper.selectById(roleId);

                    RoleDetail roleDetail = new RoleDetail();

                    roleDetail.setRole(role);

                    //根据roleId查询该角色具有的权限
                    List<Permission> permissionList = new ArrayList<>();

                    //获取角色具有的权限
                    QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
                    rolePermissionQueryWrapper.eq("role_id", role.getRoleId());
                    List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionQueryWrapper);

                    if (rolePermissions != null) {
                        for (RolePermission rolePermission : rolePermissions) {
                            Long permissionId = rolePermission.getPermissionId();
                            Permission permission = permissionMapper.selectById(permissionId);
                            permissionList.add(permission);
                        }

                        //roleDetail实体类赋值完成
                        roleDetail.setPermission(permissionList);
                        roleDetailList.add(roleDetail);
                    } else {
                        log.error("查询不到该用户对应的角色的相关权限，username=" + username + ",roleName=" + role.getRoleName());
                        return new JsonResult(500,"查询不到该用户对应角色的相关权限");
                    }

                }

                userDetail.setRoleDetail(roleDetailList);
                return new JsonResult(userDetail,200,"查询用户详细信息成功");

            } else {
                log.error("查询不到该用户所具有的角色，username={}", username);
                return new JsonResult(500,"查询不到该用户所具有的角色");
            }
        } else {
            log.error("查询不到相应用户，userName={}", username);
            return new JsonResult(500,"查询不到相应用户");
        }
    }

    @Override
    public JsonResult getUserByName(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUsername,username);
        List<User> users = userMapper.selectList(queryWrapper);
        if(users != null){
            if(users.size() == 1){
                return new JsonResult(users.get(0),200,"查询用户个人信息成功");
            }else if(users.size() > 1){
                return new JsonResult(500,"数据库中存在重复用户名");
            }else {
                return new JsonResult(500,"查询不到该用户的个人信息");
            }
        }else {
            return new JsonResult(500,"查询用户个人信息失败");
        }
    }

    @Override
    public JsonResult searchUser(Integer current,Integer size,String username) {
        if(username != null){
            Page<User> page = new Page<>(current,size);
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().like(User::getUsername,username);

            Page<User> userPage = userMapper.selectPage(page, queryWrapper);
            if(userPage != null && userPage.getRecords().size() > 0){
                log.info("size:{}",userPage.getRecords().size());
                return new JsonResult(userPage,200,"搜索用户成功");
            }else {
                return new JsonResult(500,"搜索用户失败");
            }
        }else {
            return new JsonResult(500,"请传入用户名");
        }
    }

    @Override
    public JsonResult deleteUserById(Long userId) {
        //先删除user_role表中的相关信息
        HashMap<String, Object> map = new HashMap<>();
        map.put("user_id", userId);
        int deleteUserRole = userRoleMapper.deleteByMap(map);
        //再删除user表中的数据
        int deleteUser = userMapper.deleteByMap(map);

        //判断是否删除成功
        if (deleteUserRole > 0 && deleteUser > 0) {
            return new JsonResult(200,"删除用户成功");
        } else {
            return new JsonResult(500,"删除用户失败");
        }

    }

    @Override
    public JsonResult updateUser(User user,Boolean isUpdateUsername) {
        if(isUpdateUsername){
            //判断用户名是否已经被注册
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(User::getUsername,user.getUsername());
            List<User> users = userMapper.selectList(queryWrapper);
            if(users.size() != 0){
                return new JsonResult(500,"该用户名已被注册，修改失败");
            }else {
                int update = userMapper.updateById(user);
                if(update > 0){
                    return new JsonResult("当前登录用户:" + user.getUsername(), 200, "用户信息修改成功");
                }else {
                    return new JsonResult("当前登录用户:" + user.getUsername(), 500, "用户信息修改失败");
                }
            }
        }else {
            int update = userMapper.updateById(user);
            if(update > 0){
                return new JsonResult("当前登录用户:" + user.getUsername(), 200, "用户信息修改成功");
            }else {
                return new JsonResult("当前登录用户:" + user.getUsername(), 500, "用户信息修改失败");
            }
        }

    }

    @Override
    public JsonResult registerUser(User user) {

        //判断用户名是否已经被注册
        JsonResult jsonResult = this.getUserByName(user.getUsername());
        if(jsonResult.getData() != null){
            return new JsonResult(500,"用户名已被注册");
        }

        //用户名未被注册 继续执行
        int insertUser = userMapper.insert(user);
        if(insertUser > 0){
            //刚注册进数据库的用户id
            Long userId = userMapper.selectUserByName(user.getUsername()).getUserId();

            //为刚注册的用户分配角色，默认为normal
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(ROLE_NORMAL_ID);

            int insertUserRole = userRoleMapper.insert(userRole);
            if(insertUserRole > 0){
                return new JsonResult("新注册的用户名:" + user.getUsername(), 200,"注册成功");
            }else {
                return new JsonResult(500,"注册失败");
            }

        }else {
            log.error("注册失败");
            return new JsonResult(500,"注册失败");
        }

    }

    @Override
    public JsonResult getUserPermissions(String username) {
        List<String> permissionList = userMapper.getPermissionsByUsername(username);
        if(permissionList != null && permissionList.size() > 0){
            return new JsonResult(permissionList,200,"获取用户权限成功");
        }
        return new JsonResult(500,"获取用户权限失败");

    }

    @Override
    public JsonResult login(String username, String password) {
        //验证该用户是否已经登录
        if(redisUtils.hasKey(username)){
            return new JsonResult(500,"用户已登录!");
        }

        //检验用户名和密码的准确性
        List<User> users = userMapper.selectList(new QueryWrapper<User>().lambda().eq(User::getUsername,username));
        if(users.size() == 0){
            return new JsonResult(500,"该用户不存在!");
        }else if(!password.equals(users.get(0).getPassword())){
            return new JsonResult(500,"密码错误!");
        }else if(users.size() > 1){
            return new JsonResult(500,"用户名重复，请及时联系管理员进行处理!");
        }

        //登录成功，将用户信息存入payload中
        HashMap<String, String> payloadMap = new HashMap<>();
        payloadMap.put("username",username);
        payloadMap.put("password",password);

        //将该用户的权限集合也存入payload中
        JsonResult jsonResult = this.getUserPermissions(username);
        List<String> permissionList = (List<String>) jsonResult.getData();
        StringBuffer permissions = new StringBuffer();
        for (int i = 0; i < permissionList.size(); i++) {
            if(i == permissionList.size() - 1){
                permissions.append(permissionList.get(i));
            }else {
                permissions.append(permissionList.get(i)).append(",");
            }
        }
        log.info("permissions : {}",permissions);
        payloadMap.put("permissions",permissions.toString());

        //生成token
        String token = JWTUtils.getToken(payloadMap);

//        //解析token测试
//        DecodedJWT tokenInfo = JWTUtils.getTokenInfo(token);
//        String permissions1 = tokenInfo.getClaim("permissions").asString();
//        log.info("解析出的permission : {}",permissions1);

        //解决单点登陆问题 -> 将用户名作为key存入redis，每次登录时先确认用户名是否已经存在
        User user = (User) this.getUserByName(username).getData();
        redisUtils.set(username,user);
        //设置redis中数据的有效时间（一天）
        redisUtils.expire(username,24*60*60);

        //判断是否为管理员
        List<String> roles = userMapper.judgeAdmin(username);
        Boolean isAdmin = false;
        for (String role : roles){
            if("admin".equals(role)){
                isAdmin = true;
            }
        }

        if(isAdmin){
            return new JsonResult(token, user, 201, "管理员登陆成功!");
        }else {
            return new JsonResult(token, user, 200, "用户登陆成功!");
        }
    }

    @Override
    public JsonResult logout(String username) {
        log.debug("当前登录的用户 : {}",username);
        if (username != null) {
            //将该用户从Redis中移除
            redisUtils.del(username);
            return new JsonResult(200, "用户退出成功!");
        }
        return new JsonResult(500,"当前未检测到由用户登录,请先登录!");
    }

    @Override
    public JsonResult pageUser(Integer current, Integer size) {
        List<UserRole> userRoles = userRoleMapper.selectList(new QueryWrapper<UserRole>().lambda().eq(UserRole::getRoleId, 2));
        List<Long> userIdList = new ArrayList<>();
        for (UserRole userRole : userRoles) {
            userIdList.add(userRole.getUserId());
        }

        Page<User> page = new Page<>(current,size);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().notIn(User::getUserId,userIdList);

        Page<User> userPage = userMapper.selectPage(page, queryWrapper);
        if(userPage != null){
            return new JsonResult(userPage,200,"分页查询用户数据成功");
        }else {
            return new JsonResult(500,"分页查询用户数据失败");
        }
    }

    @Override
    public JsonResult addUser(User user) {
        //判断用户名是否已经被注册
        JsonResult jsonResult = this.getUserByName(user.getUsername());
        if(jsonResult.getData() != null){
            return new JsonResult(500,"该用户名已存在");
        }

        //用户名未被注册 继续执行
        int insertUser = userMapper.insert(user);
        if(insertUser > 0){
            //刚注册进数据库的用户id
            Long userId = userMapper.selectUserByName(user.getUsername()).getUserId();

            //为刚注册的用户分配角色，默认为normal
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(ROLE_NORMAL_ID);

            int insertUserRole = userRoleMapper.insert(userRole);
            if(insertUserRole > 0){
                return new JsonResult("用户名:" + user.getUsername(), 200,"添加用户成功");
            }else {
                return new JsonResult(500,"添加用户失败");
            }

        }else {
            return new JsonResult(500,"添加用户失败");
        }
    }

    @Override
    public JsonResult updateAdminPassword(String oldPassword,String newPassword) {
        if(!StringUtils.isEmpty(newPassword) && !"null".equals(newPassword) && !StringUtils.isEmpty(oldPassword) && !"null".equals(oldPassword)){
            //管理员的userId永远为1
            User user = userMapper.selectById(1);
            if(!oldPassword.equals(user.getPassword())){
                return new JsonResult(500,"原密码错误");
            }

            user.setPassword(newPassword);
            int update = userMapper.updateById(user);
            if(update > 0){
                return new JsonResult(200,"密码修改成功");
            }else {
                return new JsonResult(500,"密码修改失败");
            }
        }else {
            return new JsonResult(500,"请传入有效的新密码");
        }
    }


}
